fix: reconcile orphaned in_progress sync_history rows on startup - #89
Open
kilo-WATT wants to merge 1 commit into
Open
fix: reconcile orphaned in_progress sync_history rows on startup#89kilo-WATT wants to merge 1 commit into
kilo-WATT wants to merge 1 commit into
Conversation
If the core sync process is interrupted mid-sync (container restart, OOM kill, host reboot, Watchtower auto-update, etc.), its sync_history row is never closed out — it stays in_progress=1, end_time=NULL forever, since nothing else updates that row after the process dies. /api/sync/status/live derives "is a sync currently running" from the most recent sync_history row's in_progress flag rather than checking whether the session's process is actually still alive. So once a row is orphaned this way, the dashboard's Sync Management page shows "Sync in Progress" permanently, with duration_seconds eventually going negative as wall-clock time outpaces the stale start_time. Restarting the container again does not fix it, since the stale row is read from the DB, not held in memory. This adds a reconciliation step to init_database(), which already runs at startup in both api_server.py and list_sync/main.py: any sync_history row still marked in_progress=1 with no end_time gets closed out as 'interrupted' with end_time set to now. Since a fresh process starting up can't have any sync from a previous process instance genuinely still running, this is safe to do unconditionally rather than trying to detect whether the recorded pid is still alive. Fixes Woahai321#88
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #88
Bug
If the core sync process is interrupted mid-sync (container restart, OOM kill, host reboot, Watchtower auto-update, etc.), its
sync_historyrow is never closed out — it staysin_progress=1,end_time=NULLforever, since nothing else updates that row after the process dies./api/sync/status/livederives "is a sync currently running" from the most recentsync_historyrow'sin_progressflag rather than checking whether that session's process is actually still alive. So once a row is orphaned this way, the dashboard's Sync Management page shows "Sync in Progress" permanently, withduration_secondseventually going negative as wall-clock time outpaces the stalestart_time. Restarting the container again does not fix it, since the stale row is read from the DB, not held in memory — see #88 for the full repro and a real example payload.Fix
Adds a reconciliation step to
init_database(), which already runs at startup in bothapi_server.pyandlist_sync/main.py: anysync_historyrow still markedin_progress=1with noend_timegets closed out as'interrupted'withend_timeset to now.Since a freshly-starting process can't have any sync from a previous process instance genuinely still running, this is safe to do unconditionally rather than trying to detect whether the recorded
pidis still alive (which would also be unreliable across container restarts, where PIDs get reused).Testing
python3 -m py_compilecleanduration_secondsUPDATEmanually against the live DB, confirmed/api/sync/status/livecorrectly returned to{"is_running": false, "status": "idle", ...}after a restartinit_database()so it happens automatically rather than requiring manual DB surgery